package com.cakeclient.Model;


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import com.cakeclient.database.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

public class ProductType implements IDatabasable {
    private Long idDB;
    private Long remoteID;
    private String name;
    private Integer idIllustration;
    private String description;
    private HashMap<Long, HashMap<Long, LocalPriceHT>> localPriceHashMap = new HashMap<Long, HashMap<Long, LocalPriceHT>>();       // DeliveryType Store
    private HashMap<Long, RecommendedPrice> recommendedPriceHashMap = new HashMap<Long, RecommendedPrice>();                                //DeliveryType
    private VATCategory vatCategory;

    public ProductType(String name) {
        this.name = name;
    }

    public ProductType(String name, int idIllustration, String description) {
        this.name = name;
        this.idIllustration = idIllustration;
        this.description = description;
    }

    private ProductType(DataSource dataSource, Cursor cursor) {
        idDB = cursor.getLong(cursor.getColumnIndexOrThrow(ProductTypeTable.ID));
        setRemoteID(cursor.getLong(cursor.getColumnIndexOrThrow(ProductTable.REMOTE_ID)));
        name = cursor.getString(cursor.getColumnIndexOrThrow(ProductTypeTable.NAME));
        idIllustration = cursor.getInt(cursor.getColumnIndexOrThrow(ProductTypeTable.ILLUSTRATION));
        description = cursor.getString(cursor.getColumnIndexOrThrow(ProductTypeTable.DESCRIPTION));
        vatCategory = VATCategory.getOne(dataSource, cursor.getColumnIndexOrThrow(ProductTypeTable.DESCRIPTION));

        //Recuperer les LocalPriceHT
        Cursor cursorLp = dataSource.getMore(this, ProductType_has_LocalPriceHT.getInstance(), ProductType_has_LocalPriceHT.ID_PRODUCTTYPE);
        cursorLp.moveToFirst();
        while (!cursorLp.isAfterLast()) {
            LocalPriceHT localPriceHT = LocalPriceHT.getOne(dataSource, cursorLp.getLong(cursorLp.getColumnIndexOrThrow(ProductType_has_LocalPriceHT.ID_PRODUCTTYPE)));
            if (localPriceHT != null) {
                if (localPriceHashMap.get(localPriceHT.getDeliveryType() == null ? null : localPriceHT.getDeliveryType().getIdDB()) == null) {
                    localPriceHashMap.put(localPriceHT.getDeliveryType() == null ? null : localPriceHT.getDeliveryType().getIdDB(), new HashMap<Long, LocalPriceHT>());
                }
                localPriceHashMap.get(localPriceHT.getDeliveryType()).put(localPriceHT.getStore() == null ? null : localPriceHT.getStore().getIdDB(), localPriceHT);
            }

            cursorLp.moveToNext();
        }

        //Recuperer les RecommendedPrice
        Cursor cursorRp = dataSource.getMore(this, ProductType_has_RecommendedPrice.getInstance(), ProductType_has_RecommendedPrice.ID_PRODUCTTYPE);
        cursorRp.moveToFirst();
        while (!cursorRp.isAfterLast()) {
            RecommendedPrice r = RecommendedPrice.getOne(dataSource, cursorRp.getLong(cursorRp.getColumnIndexOrThrow(ProductType_has_RecommendedPrice.ID_RECOMMENDEDPRICE)));
            this.recommendedPriceHashMap.put(r.getDeliveryType() == null ? null : r.deliveryType.getIdDB(), r);
            cursorRp.moveToNext();

        }
    }

    public ProductType(Context context, com.cakeclient.clientsoap.contract.ProductType productType) {
        this.remoteID = Long.valueOf(productType.id);
        this.name = productType.name;
        this.description = productType.description;
        this.vatCategory = new VATCategory(context, productType.vat);
        try {
            if (!productType.illustration.equals(""))
                this.idIllustration = Integer.parseInt(productType.illustration);
        } catch (Exception e) {
        }
//        if (productType.localPrices != null)
//            for (com.cakeclient.clientsoap.contract.LocalPriceHT localPriceHT : productType.localPrices) {
//                LocalPriceHT localPriceHT1 = new LocalPriceHT(context, localPriceHT);
//            }
    }

    public HashMap<Long, HashMap<Long, LocalPriceHT>> getLocalPriceHashMap() {
        return localPriceHashMap;
    }

    public HashMap<Long, RecommendedPrice> getRecommendedPriceHashMap() {
        return recommendedPriceHashMap;
    }

    public Long getRemoteID() {
        return remoteID;
    }

    private void setRemoteID(Long remoteID) {
        this.remoteID = remoteID;
    }

    public Long getIdDB() {
        return idDB;
    }

    public void setIdDB(Long idDB) {
        this.idDB = idDB;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getIdIllustration() {
        return idIllustration;
    }

    public void setIdIllustration(Integer idIllustration) {
        this.idIllustration = idIllustration;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public VATCategory getVatCategory() {
        return vatCategory;
    }

    public void setVatCategory(VATCategory vatCategory) {
        this.vatCategory = vatCategory;
    }

    @Override
    public ContentValues getValues() {
        ContentValues values = new ContentValues();
        values.put(ProductTypeTable.REMOTE_ID, this.getRemoteID());
        values.put(ProductTypeTable.NAME, this.name);
        values.put(ProductTypeTable.ILLUSTRATION, this.getIdIllustration());
        values.put(ProductTypeTable.DESCRIPTION, this.getDescription());
        values.put(ProductTypeTable.ID_VATCATEGORY, this.getVatCategory() != null ? this.getVatCategory().getIdDB() : null);
        return values;
    }


    @Override
    public void saveToDatabase(Context context) {
        //Protection anti-doublons
        ProductType bis = null;
        if (this.getIdDB() == null && this.getRemoteID() != null && (bis = ProductType.getOneFromRemoteID(context, this.getRemoteID())) != null) {
            this.setIdDB(bis.getIdDB());
        }

        if (this.vatCategory != null) {
            this.vatCategory.saveToDatabase(context);
        }
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        if (this.getIdDB() == null) {
            dataSource.insert(this, ProductTypeTable.getInstance());
        } else {
            dataSource.update(this, ProductTypeTable.getInstance());
            dataSource.delete(this, ProductType_has_LocalPriceHT.getInstance(), ProductType_has_LocalPriceHT.ID_PRODUCTTYPE);
            dataSource.delete(this, ProductType_has_RecommendedPrice.getInstance(), ProductType_has_RecommendedPrice.ID_PRODUCTTYPE);
        }
        {


            Iterator<HashMap<Long, LocalPriceHT>> enu = this.getLocalPriceHashMap().values().iterator();
            while (enu.hasNext()) {
                HashMap<Long, LocalPriceHT> dico = enu.next();
                Iterator<LocalPriceHT> enuL = dico.values().iterator();
                while (enuL.hasNext()) {
                    LocalPriceHT l = enuL.next();
                    l.saveToDatabase(context);
                    dataSource.insert(ProductType_has_LocalPriceHT.getInstance(), this.getIdDB(), l.getIdDB());
                }
            }

            Iterator<RecommendedPrice> enur = this.getRecommendedPriceHashMap().values().iterator();
            while (enur.hasNext()) {
                RecommendedPrice r = enur.next();
                r.saveToDatabase(context);
                dataSource.insert(ProductType_has_RecommendedPrice.getInstance(), this.getIdDB(), r.getIdDB());
            }

        }
        dataSource.close();
    }

    @Override
    public void removeFromDatabase(Context context) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        dataSource.delete(this, ProductTypeTable.getInstance());
        dataSource.delete(this, ProductType_has_LocalPriceHT.getInstance(), ProductType_has_LocalPriceHT.ID_PRODUCTTYPE);
        dataSource.delete(this, ProductType_has_RecommendedPrice.getInstance(), ProductType_has_RecommendedPrice.ID_PRODUCTTYPE);
        dataSource.close();
    }

    public static ProductType getOne(Context context, Long idDB) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchOne(idDB, ProductTypeTable.getInstance());
        cursor.moveToFirst();
        ProductType item = null;
        while (!cursor.isAfterLast()) {
            item = new ProductType(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        dataSource.close();
        return item;
    }

    public static List<ProductType> getAll(Context context) {
        List<ProductType> result = new ArrayList<ProductType>();
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchAll(ProductTypeTable.getInstance());
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            result.add(new ProductType(dataSource, cursor));
            cursor.moveToNext();
        }
        dataSource.close();
        return result;
    }

    public static ProductType getOne(DataSource dataSource, long idDB) {
        Cursor cursor = dataSource.fetchOne(idDB, ProductTypeTable.getInstance());
        cursor.moveToFirst();
        ProductType item = null;
        while (!cursor.isAfterLast()) {
            item = new ProductType(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        return item;
    }

    public static ProductType getOneFromRemoteID(Context context, long remoteID) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchOneFromRemoteID(remoteID, ProductTypeTable.getInstance());
        cursor.moveToFirst();
        ProductType item = null;
        while (!cursor.isAfterLast()) {
            item = new ProductType(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        dataSource.close();
        return item;
    }

    public Float getLocalPrice(Store s) {
        if (this.localPriceHashMap != null) {
            if (this.localPriceHashMap.get(null) != null && s != null)
                if (this.localPriceHashMap.get(null).get(s.getIdDB()) != null) {
                    return this.localPriceHashMap.get(null).get(s.getIdDB()).getValue();
                }
        }
        return 0f;
    }

    public void setLocalPrice(Store store, DeliveryType deliveryType, Float value) {
        if (this.getLocalPriceHashMap().get(deliveryType == null ? null : deliveryType.getIdDB()) == null) {
            this.getLocalPriceHashMap().put(deliveryType == null ? null : deliveryType.getIdDB(), new HashMap<Long, LocalPriceHT>());
        }
        this.getLocalPriceHashMap().get(deliveryType == null ? null : deliveryType.getIdDB()).put(store.getIdDB(), new LocalPriceHT(value, deliveryType, store));
    }

    public Float getVat() {
        if (this.vatCategory != null) {
            return this.getVatCategory().getValue();
        }
        return null;
    }

    public Float getVatOrDefault() {
        if (this.vatCategory != null) {
            return this.getVatCategory().getValue();
        }
        return 19.6f;
    }
}
